package com.simon.train.business.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.simon.train.business.domain.DailyTrainTicket;
import com.simon.train.business.domain.DailyTrainTicketExample;
import com.simon.train.business.domain.TrainStation;
import com.simon.train.business.dto.DailyTrainTicketQueryDto;
import com.simon.train.business.dto.DailyTrainTicketSaveDto;
import com.simon.train.business.enums.SeatTypeEnum;
import com.simon.train.business.enums.TrainTypeEnum;
import com.simon.train.business.mapper.DailyTrainTicketMapper;
import com.simon.train.business.vo.DailyTrainTicketQueryVO;
import com.simon.train.common.util.SnowUtil;
import com.simon.train.common.vo.PageVO;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

@Service
public class DailyTrainTicketService {

    private static final Logger LOG = LoggerFactory.getLogger(DailyTrainTicketService.class);

    @Resource
    private DailyTrainTicketMapper dailyTrainTicketMapper;

    @Resource
    private TrainStationService trainStationService;

    @Resource
    private DailyTrainSeatService dailyTrainSeatService;

    public void SaveDailyTrainTicket(DailyTrainTicketSaveDto dailyTrainTicketSaveDto){
        DailyTrainTicket dailyTrainTicket = BeanUtil.copyProperties(dailyTrainTicketSaveDto, DailyTrainTicket.class);
        if (ObjectUtil.isNull(dailyTrainTicket.getId())){
            //对于首次保存 也就是新增 需要对字段单独做处理
            dailyTrainTicket.setId(SnowUtil.getSnowflakeNextId());
            DateTime time = DateTime.now();
            dailyTrainTicket.setCreateTime(time);
            dailyTrainTicket.setUpdateTime(time);
            dailyTrainTicketMapper.insert(dailyTrainTicket);
        } else {
            dailyTrainTicket.setUpdateTime(DateTime.now());
            dailyTrainTicketMapper.updateByPrimaryKey(dailyTrainTicket);
        }

    }

    public PageVO<DailyTrainTicketQueryVO> QueryDailyTrainTicketList(DailyTrainTicketQueryDto dailyTrainTicketQueryDto){
        DailyTrainTicketExample dailyTrainTicketExample = new DailyTrainTicketExample();
        dailyTrainTicketExample.setOrderByClause("id desc");
        DailyTrainTicketExample.Criteria criteria = dailyTrainTicketExample.createCriteria();

        if(ObjectUtil.isNotNull(dailyTrainTicketQueryDto.getDate())) criteria.andDateEqualTo(dailyTrainTicketQueryDto.getDate());

        if(ObjectUtil.isNotEmpty(dailyTrainTicketQueryDto.getTrainCode())) criteria.andTrainCodeEqualTo(dailyTrainTicketQueryDto.getTrainCode());

        if(ObjectUtil.isNotEmpty(dailyTrainTicketQueryDto.getStart())) criteria.andStartEqualTo(dailyTrainTicketQueryDto.getStart());

        if(ObjectUtil.isNotEmpty(dailyTrainTicketQueryDto.getEnd())) criteria.andEndEqualTo(dailyTrainTicketQueryDto.getEnd());

        LOG.info("当前请求的页码：{}", dailyTrainTicketQueryDto.getPage());
        LOG.info("每页条数：{}", dailyTrainTicketQueryDto.getPageSize());

        PageHelper.startPage(dailyTrainTicketQueryDto.getPage(),dailyTrainTicketQueryDto.getPageSize());
        List<DailyTrainTicket> dailyTrainTicketList = dailyTrainTicketMapper.selectByExample(dailyTrainTicketExample);

        PageInfo<DailyTrainTicket> pageInfo = new PageInfo<>(dailyTrainTicketList);
        LOG.info("总行数：{}", pageInfo.getTotal());
        LOG.info("总页数：{}", pageInfo.getPages());

        List<DailyTrainTicketQueryVO> lists = BeanUtil.copyToList(dailyTrainTicketList, DailyTrainTicketQueryVO.class);
        PageVO<DailyTrainTicketQueryVO> pageVO = new PageVO<>();
        pageVO.setList(lists);
        pageVO.setTotal(pageInfo.getTotal());

        return pageVO;
    }

    public void deleteDailyTrainTicket(Long id) {
        dailyTrainTicketMapper.deleteByPrimaryKey(id);
    }

    @Transactional
    public void GenerateDailyTrainTicket(String TrainType, String trainCode, Date date){
        LOG.info("生成日期【{}】的车次【{}】余票信息开始", DateUtil.formatDate(date),trainCode);

        /**
         * 删除现有的余票信息
         */
        DailyTrainTicketExample dailyTrainTicketExample = new DailyTrainTicketExample();
        dailyTrainTicketExample.createCriteria()
                .andTrainCodeEqualTo(trainCode)
                .andDateEqualTo(date);
        dailyTrainTicketMapper.deleteByExample(dailyTrainTicketExample);

        List<TrainStation> trainStations = trainStationService.SelectByTrainCode(trainCode);
        if(CollUtil.isEmpty(trainStations)){
            LOG.info("改车次没有车站信息，生成结束");
            LOG.info("生成日期【{}】的车次【{}】余票信息结束", DateUtil.formatDate(date),trainCode);
            return;
        }

        /**
         * 当前列车的类型对应的车次的基数价格 通过EnumUtil获取
         */
        BigDecimal TrainTypeToBasePrice = EnumUtil.getFieldBy(TrainTypeEnum::getPriceRate, TrainTypeEnum::getCode, TrainType);

        for (int i = 0; i < trainStations.size(); i++) {
            TrainStation trainStationStart = trainStations.get(i);
            BigDecimal kmNum = BigDecimal.ZERO;
            for (int j = (i+1); j < trainStations.size(); j++) {
                TrainStation trainStationEnd = trainStations.get(j);
                kmNum = kmNum.add(trainStationEnd.getKm());
                DailyTrainTicket dailyTrainTicket = new DailyTrainTicket();
                dailyTrainTicket.setId(SnowUtil.getSnowflakeNextId());
                dailyTrainTicket.setDate(date);
                dailyTrainTicket.setTrainCode(trainCode);
                dailyTrainTicket.setStart(trainStationStart.getName());
                dailyTrainTicket.setStartPinyin(trainStationStart.getNamePinyin());
                dailyTrainTicket.setStartTime(trainStationStart.getOutTime());
                dailyTrainTicket.setStartIndex(trainStationStart.getIndex());
                dailyTrainTicket.setEnd(trainStationEnd.getName());
                dailyTrainTicket.setEndPinyin(trainStationEnd.getNamePinyin());
                dailyTrainTicket.setEndTime(trainStationEnd.getInTime());
                dailyTrainTicket.setEndIndex(trainStationEnd.getIndex());
                dailyTrainTicket.setYdz(dailyTrainSeatService.CountSeatNumberByType(trainCode, date, SeatTypeEnum.YDZ.getCode()));
                /**
                 * 票价格的计算
                 * 比如ABCD四个站 对于C站 km熟练为AB+BC的 所以需要循环计算公里数
                 * price = 公里数 * 车次对应的每公里票价 * 车次对应的基数
                 * 公里数kmNum 已经通过循环计算了
                 * 车次对应的每公里票价为SeatTypeEnum 可以直接获取
                 * 车次的基数需要单独获取
                 */
                BigDecimal YDZPrice = kmNum.multiply(SeatTypeEnum.YDZ.getPrice()).multiply(TrainTypeToBasePrice).setScale(2, RoundingMode.HALF_UP);
                dailyTrainTicket.setYdzPrice(YDZPrice);
                dailyTrainTicket.setEdz(dailyTrainSeatService.CountSeatNumberByType(trainCode, date, SeatTypeEnum.EDZ.getCode()));
                BigDecimal EdzPrice = kmNum.multiply(SeatTypeEnum.EDZ.getPrice()).multiply(TrainTypeToBasePrice).setScale(2, RoundingMode.HALF_UP);
                dailyTrainTicket.setEdzPrice(EdzPrice);
                dailyTrainTicket.setRw(dailyTrainSeatService.CountSeatNumberByType(trainCode, date, SeatTypeEnum.RW.getCode()));
                BigDecimal RWPrice = kmNum.multiply(SeatTypeEnum.RW.getPrice()).multiply(TrainTypeToBasePrice).setScale(2, RoundingMode.HALF_UP);
                dailyTrainTicket.setRwPrice(RWPrice);
                dailyTrainTicket.setYw(dailyTrainSeatService.CountSeatNumberByType(trainCode, date, SeatTypeEnum.YW.getCode()));
                BigDecimal YWPrice = kmNum.multiply(SeatTypeEnum.YW.getPrice()).multiply(TrainTypeToBasePrice).setScale(2, RoundingMode.HALF_UP);
                dailyTrainTicket.setYwPrice(YWPrice);
                DateTime time = DateTime.now();
                dailyTrainTicket.setCreateTime(time);
                dailyTrainTicket.setUpdateTime(time);
                dailyTrainTicketMapper.insert(dailyTrainTicket);
            }
        }

        LOG.info("生成日期【{}】的车次【{}】余票信息结束", DateUtil.formatDate(date),trainCode);
    }
}
